#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QMainWindow>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>
#include <QLabel>
#include <QList>
#include <QProcess>
#include <QResource>

#include "codeview.hpp"
#include "breakpoints.hpp"
#include "papview.hpp"
#include "registerview.hpp"
#include "sevensegmentview.hpp"
#include "stackview.hpp"
#include "watchlist.hpp"
#include "appsettings.hpp"
#include "pix.hpp"
#include "hardwareinterfaceview.hpp"

class Pix;
class CodeView;
class PapView;
class WatchList;

namespace Ui {
    class MainWindow;
}

/**
* @brief
*
* @class MainWindow mainwindow.hpp "mainwindow.hpp"
*/
class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    /**
    * @brief Constructor for MainWindow
    *
    * @fn MainWindow(QWidget *parent = 0)
    * @param parent
    */
    MainWindow(QWidget *parent = 0);

    /**
    * @brief Destructor for MainWindow
    *
    * @fn ~MainWindow()
    */
    ~MainWindow();

    /**
    * @brief Action on close
    *
    * @fn void closeEvent(QCloseEvent *)
    * @param ce
    */
    void closeEvent(QCloseEvent *ce);

    /**
    * @brief Resets the Registers and the Program Counter after a Watchdog Timeout
    *
    * @fn void resetToProgramStart()
    */
    void resetToProgramStart();

    /**
    * @brief Returns the RegisterView as pointer
    *
    * @fn RegisterView *getRegisterView()
    * @return RegisterView
    */
    RegisterView *getRegisterView();

protected:
    /**
    * @brief Action on ChangeEvent
    *
    * @fn void changeEvent(QEvent *e)
    * @param e
    */
    void changeEvent(QEvent *e);

private:
    Ui::MainWindow *ui;
    CodeView *codeView;
    Breakpoints *breakpointView;
    PapView *papView;
    RegisterView *registerView;
    StackView *stackView;
    WatchList *watchList;
    AppSettings *appSettings;
    QMessageBox *msgBoxWatchdogTimeout;
    Pix *pix;
    HardwareInterfaceView *hwInterfaceView;
    QList<SevenSegmentView*> sevenSegList;
    int sevenSegCount;
    QLabel *runtime;
    QLabel *watchdog;
    QLabel *information;

private slots:
    /**
    * @brief Triggered when actionOpen comes up
    * @details File->Open
    *
    * @fn void on_actionOpen_triggered()
    */
    void on_actionOpen_triggered();

    /**
    * @brief Triggered when actionNew comes up
    * @details File->New
    *
    * @fn void on_actionNew_triggered()
    */
    void on_actionNew_triggered();

    /**
    * @brief Triggered when actionClose comes up
    * @details File->Close
    *
    * @fn void on_actionClose_triggered()
    */
    void on_actionClose_triggered();

    /**
    * @brief Triggered when actionStart comes up
    *
    * @fn void on_actionStart_triggered()
    */
    void on_actionStart_triggered();

    /**
    * @brief Triggered when actionStop comes up
    *
    * @fn void on_actionStop_triggered()
    */
    void on_actionStop_triggered();

    /**
    * @brief Triggered when actionTrace comes up
    *
    * @fn void on_actionTrace_triggered()
    */
    void on_actionTrace_triggered();

    /**
    * @brief Triggered when actionPause comes up
    *
    * @fn void on_actionPause_triggered()
    */
    void on_actionPause_triggered();

    void on_actionSevenSegment_triggered();

    /**
    * @brief Action on watchdog timeout
    *
    * @fn void onWatchdogTimeout()
    */
    void onWatchdogTimeout();

    /**
    * @brief Updates the statusbar
    *
    * @fn void updateStatusbar()
    */
    void updateStatusbar();

    /**
    * @brief Action after the code file has parsed
    *
    * @fn void onCodeFileParsed()
    */
    void onCodeFileParsed();

    /**
    * @brief Reset occured
    *
    * @fn void onReset()
    */
    void onReset();

    /**
    * @brief Enables and disables the buttons after the simulationstate has changed
    *
    * @fn void onSimulationStateChanged(bool state)
    * @param state
    */
    void onSimulationStateChanged(bool state);

    /**
    * @brief Triggered when a register is changed in the GUI
    *
    * @fn void onRequestChangeRegister(int address, int value)
    * @param address
    * @param value
    */
    void onRequestChangeRegister(int address, int value);

    /**
    * @brief
    *
    * @fn void onManualSend()
    */
    void onManualSend();

    /**
    * @brief
    *
    * @fn void onManualReceive(QString data)
    * @param data
    */
    void onManualReceive(QString data);

    /**
    * @brief About clicked
    *
    * @fn void on_actionAbout_triggered()
    */
    void on_actionAbout_triggered();

    /**
    * @brief Help clicked
    *
    * @fn void on_actionHelp_triggered()
    */
    void on_actionHelp_triggered();

signals:
    void reset();
    void start();
    void stop();
    void pause();
    void trace();
    void parseLstFile(QString filename);
    void requestChangeBank(bool);

};

#endif // MAINWINDOW_HPP
